package OOPAndMultiThreadArchiveManager.Server.Controllers;

import OOPAndMultiThreadArchiveManager.Server.Entities.Archive;
import OOPAndMultiThreadArchiveManager.Server.Entities.UserInfo;
import OOPAndMultiThreadArchiveManager.Server.Entities.DbContext;
import OOPAndMultiThreadArchiveManager.Server.Models.ApiReceive;
import OOPAndMultiThreadArchiveManager.Server.Models.ApiResponse;
import OOPAndMultiThreadArchiveManager.Server.Models.UserChange;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.List;
import java.util.regex.Pattern;

public class UserController {
    private ApiReceive receive;
    private ObjectMapper objectMapper = new ObjectMapper();
    private DbContext dbContext = new DbContext();

    public UserController(ApiReceive receive) {
        this.receive = receive;
    }

    public ApiResponse actionResult() {
        if (!receive.user.isValid()) {
            return ApiResponse.Unauthorized();
        }
        switch (receive.api) {
            case POST_User:
                return this.signIn();
            case POST_Login:
                return this.login();
            case DELETE_User:
                return this.deleteUser();
            case GET_UserList:
                return this.queryUserList();
            case PUT_User:
                return this.changeUserInfo();
            case POST_Archive:
                return this.uploadFile();
            case GET_ArchiveList:
                return this.queryArchiveList();
            case PUT_User$Password:
                return this.changePassword();
            default:
                return ApiResponse.Failed("未知的请求");
        }
    }

    /**
     * user: Administrator
     * object: UserInfo
     * @return SignIn Result
     */
    public ApiResponse signIn() {
        var authorize = !dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, "Administrator"),
                List.of("user", "password", "role")).isEmpty();
        if (!authorize) {
            return ApiResponse.Unauthorized();
        }
        var user = objectMapper.convertValue(receive.data, UserInfo.class);
        if (!user.isValid()) {
            return ApiResponse.Failed("非法的用户名或密码");
        }
        var isExistUserName = !dbContext.select(user,List.of("user")).isEmpty();
        if (isExistUserName) {
            return ApiResponse.Failed("用户名重复，请重新选择用户名");
        }
        return dbContext.insert(user) == 0 ? ApiResponse.Failed("数据库错误") : ApiResponse.Success(null);
    }

    /**
     * user: Any user
     * object: null
     * @return role
     */
    public ApiResponse login() {
        var user = dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, null),
                List.of("user","password"));
        if (user.isEmpty()) {
            return ApiResponse.Unauthorized();
        } else {
            return ApiResponse.Success(user.get(0).role);
        }
    }

    /**
     * user: Administrator
     * object: username
     * @return delete result
     */
    public ApiResponse deleteUser() {
        var authorize = !dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, "Administrator"),
                List.of("user", "password", "role")).isEmpty();
        if (!authorize) {
            return ApiResponse.Unauthorized();
        }
        var username = objectMapper.convertValue(receive.data, String.class);
        if (!Pattern.compile("^[a-zA-Z\\d._]{1,128}$").matcher(username).matches()) {
            return ApiResponse.Failed("非法的用户名");
        }
        var SQLResult = dbContext.delete(new UserInfo(username, null, null), List.of("user"));
        return SQLResult == 0 ? ApiResponse.Failed("数据库错误") : ApiResponse.Success(null);
    }

    /**
     * user: Administrator
     * object: null
     * @return query result or unauthorized
     */
    public ApiResponse queryUserList() {
        var authorize = !dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, "Administrator"),
                List.of("user", "password", "role")).isEmpty();
        if (!authorize) {
            return ApiResponse.Unauthorized();
        }
        return ApiResponse.Success(dbContext.select(new UserInfo(),List.of()).toArray());
    }

    /**
     * user: Administrator
     * object: UserChange
     * @return change result
     */
    public ApiResponse changeUserInfo() {
        var authorize = !dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, "Administrator"),
                List.of("user", "password", "role")).isEmpty();
        if (!authorize) {
            return ApiResponse.Unauthorized();
        }
        var userChange = objectMapper.convertValue(receive.data, UserChange.class);
        if (!userChange.isValid()) {
            return ApiResponse.Failed("非法的用户名或密码");
        }
        var SQLResult = dbContext.update(userChange.changedUserInfo,List.of("user"), List.of(userChange.originUserName));
        return SQLResult == 0 ? ApiResponse.Failed("数据库错误") : ApiResponse.Success(null);
    }

    /**
     * user: Operator
     * object: Archive
     * @return upload result
     */
    public ApiResponse uploadFile() {
        var authorize1 = !dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, "Administrator"),
                List.of("user", "password", "role")).isEmpty();
        var authorize2 = !dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, "Operator"),
                List.of("user", "password", "role")).isEmpty();
        if (!(authorize1 || authorize2)) {
            return ApiResponse.Unauthorized();
        }
        var archive = objectMapper.convertValue(receive.data, Archive.class);
        if (!dbContext.select(
                new Archive(0, null, archive.fileName, null, null, null),
                List.of("fileName")).isEmpty()) {
            return ApiResponse.Failed("上传了重复的文件");
        }
        return dbContext.insert(archive) == 0 ? ApiResponse.Failed("数据库错误") : ApiResponse.Success(null);
    }

    /**
     * user: Any User
     * object: null
     * @return query result
     */
    public ApiResponse queryArchiveList() {
        var user = dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, null),
                List.of("user","password"));
        if (user.isEmpty()) {
            return ApiResponse.Unauthorized();
        }
        return ApiResponse.Success(dbContext.select(new Archive(), List.of()));
    }

    /**
     * user: Any User
     * object: new password
     * @return success or failed
     */
    public ApiResponse changePassword() {
        var user = dbContext.select(
                new UserInfo(receive.user.name, receive.user.password, null),
                List.of("user","password"));
        if (user.isEmpty()) {
            return ApiResponse.Unauthorized();
        }
        var password = objectMapper.convertValue(receive.data, String.class);
        if (!Pattern.compile("^[a-zA-Z\\d._]{1,128}$").matcher(password).matches()) {
            return ApiResponse.Failed("非法的密码");
        }
        user.get(0).password = password;
        var SQLResult = dbContext.update(user.get(0), List.of("user"), List.of(user.get(0).user));
        return SQLResult == 0 ? ApiResponse.Failed("数据库错误") : ApiResponse.Success(null);
    }
}
